package com.syl.auth.handle;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.syl.auth.model.ResultVO;
import com.syl.auth.utils.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SmallAuthenticationFailureHandler
 * @Description 登录失败处理器
 * @Author YunLong
 * @Date 2023/5/3 11:35
 */
@Component
public class SmallAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Autowired
    ApplicationContext context;

    LoginFailureResultHandler resultHandler = new DefaultLoginFailureResultHandler();



    @PostConstruct
    public void init() {
        Map<String, LoginFailureResultHandler> beansMap = context.getBeansOfType(LoginFailureResultHandler.class);

        Collection<LoginFailureResultHandler> values = beansMap.values();

        if (!CollectionUtils.isEmpty(values)) {
            LoginFailureResultHandler[] array = values.toArray(new LoginFailureResultHandler[0]);
            resultHandler = array[0];
        }
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        Object result = resultHandler.handleResult(exception);
        out.write(new ObjectMapper().writeValueAsString(result));
        out.flush();
        out.close();
    }


    public static class DefaultLoginFailureResultHandler implements LoginFailureResultHandler {

        @Override
        public Object handleResult(AuthenticationException exception) {

            String code = SecurityUtil.authenticationFailedCode;
            String msg = "";

            if (exception instanceof LockedException) {
                msg = "账户被锁定!";
            } else if (exception instanceof DisabledException) {
                msg = "账户被禁用!";
            } else if (exception instanceof BadCredentialsException) {
                msg = "用户名或者密码输入错误!";
            } else if (exception instanceof AuthenticationServiceException) {
                msg = exception.getMessage();
            }

            return ResultVO.error(code, msg);
        }
    }
}
